package vn.vfriends.id.filter;

import java.io.IOException;
import java.util.Set;
import javax.faces.application.ResourceHandler;
import javax.inject.Inject;
import javax.servlet.*;
import javax.servlet.annotation.WebFilter;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import vn.vfriends.id.jpa.entity.Page;
import vn.vfriends.id.jpa.entity.Role;
import vn.vfriends.id.jpa.entity.User;
import vn.vfriends.id.service.PageService;

/**
 *
 * @author tuan@vfriends.vn
 */
@WebFilter(filterName="SecurityFilter", urlPatterns="/*")
public class SecurityFilter implements Filter {

    private final Logger logger = LoggerFactory.getLogger(SecurityFilter.class);
    @Inject private PageService pageService;
    
    @Override
    public void init(FilterConfig filterConfig) throws ServletException {}

    @Override
    public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException {
        HttpServletRequest hreq = (HttpServletRequest) request;
        
        String servletPath = hreq.getServletPath();
        String pathInfo = hreq.getPathInfo();
        String queryString = hreq.getQueryString();
        
        String link = servletPath
                + (pathInfo != null ? pathInfo : "");
        
        //  Ignore resource links
        if (!link.startsWith(ResourceHandler.RESOURCE_IDENTIFIER) && link.indexOf("resources") < 0) {
            Page page = this.pageService.findByLink(link);
            if (page == null) {
                logger.warn("Link " + link + " is not defined.");
            } else if (page.getRole() == null) {
                logger.warn("Link " + link + " is not in any role.");
            } else {
                HttpSession session = hreq.getSession(true);
                User loggedUser = (User) session.getAttribute("LOGGED_USER");
                if (loggedUser == null) {
                    HttpServletResponse resp = (HttpServletResponse) response;
                    resp.sendRedirect(hreq.getContextPath() + "/login.jsf");
                    return;
                } else {
                    Set<Role> roles = (Set<Role>) session.getAttribute("LOGGED_USER_ROLES");
                    if (roles == null || !roles.contains(page.getRole())) {
                        HttpServletResponse resp = (HttpServletResponse) response;
                        resp.sendRedirect(hreq.getContextPath() + "/403.jsf");
                        return;
                    }
                }
            }
        }
        chain.doFilter(request, response);
    }

    @Override
    public void destroy() {}
}
